'use strict'

var localVideo = document.querySelector('video#localvideo');
var remoteVideo = document.querySelector('video#remotevideo');

var btnConn = document.querySelector('button#connserver');
var btnLeave = document.querySelector('button#leave');

var localStream = null;

var roomid = 'rtsp';
var socket = null;

var state = 'init';

var pc = null;

var pcConfig = {
  'iceServers': [{
    'urls': 'turn:121.41.76.43:3478',
    'credential': '123456',
    'username': 'huang'
  }]
}

function sendMessage (roomid, data) {
  if (socket) {
    console.log('推送更改信息到-----------------scoket',roomid, data);
    socket.emit('message', roomid, data);
  }
}

function getAnswer (desc) {
  pc.setLocalDescription(desc);
  sendMessage(roomid, desc);
}

function handleAnswerError (err) {
  console.error('Failed to get Answer!', err);
}

function getOffer (desc) {

  pc.setLocalDescription(desc);
  sendMessage(roomid, desc)
}
function handleOfferError (err) {
  console.error('Failed to get Offer!', err);
}

//接收远端流通道
function call () {
  if (state === 'joined_conn') {
    if (pc) {
      var options = {
        offerToReceiveAudio: 1,
        offerToReceiveVideo: 1
      }
      pc.createOffer(options)
        .then(getOffer)
        .catch(handleOfferError);
    }
  }
}

// 第一步：开始服务
function connSignalServer () {
  //开启本地视频
  start();
  return true;
}

function conn () {
  //1 触发socke连接
  socket = io.connect();

  //2 加入房间后的回调
  socket.on('joined', (roomid, id) => {
    console.log('加入房间后的回调');
    state = 'joined';

    createPeerConnection();

    btnConn.disabled = true;
    btnLeave.disabled = false;

    console.log("本地开始使用远程数据播放", state);
  });
  socket.on('otherJoin', (roomid, id) => {
    console.log('用户数量', state, state === 'joined_unbind');
    if (state === 'joined_unbind') {
      createPeerConnection();
    }
    state = 'joined_conn';

    //媒体协商
    call();
    console.log("reveive otherjoin message:state=", state);
  });
  socket.on('full', (roomid, id) => {
    console.log('receive full message ', roomid, id);

    closePeerConnection();
    closeLocalMedia();

    state = 'leaved';

    btnConn.disabled = false;
    btnLeave.disabled = true;
    console.log("reveive full message:state=", state);
    alert("the room is full!");
  });

  socket.on('leaved', (roomid, id) => {

    state = 'leaved';
    socket.disconnect();
    btnConn.disabled = false;
    btnLeave.disabled = true;
    console.log("reveive leaved message:state=", state);
  });

  socket.on('exit', (roomid, id) => {

    state = 'joined_unbind';
    closePeerConnection();
    console.log("reveive exit message:state=", state);
  });
  socket.on('disconnect', (socket) => {
    console.log('receive disconnect message!', roomid);
    if (!(state === 'leaved')) {
      closePeerConnection();
      closeLocalMedia();
    }
    state = 'leaved';

  });
  socket.on('message', (roomid, data) => {
    console.log('信息中', data);
    //媒体协商
    if (data) {
      if (data.type === 'offer') {
        pc.setRemoteDescription(new RTCSessionDescription(data));
        pc.createAnswer()
          .then(getAnswer)
          .catch(handleAnswerError);
      } else if (data.type === 'answer') {
        console.log("reveive client message=====>", data);
        pc.setRemoteDescription(new RTCSessionDescription(data));
      } else if (data.type === 'candidate') {
        var candidate = new RTCIceCandidate({
          sdpMLineIndex: data.label,
          candidate: data.candidate
        });
        pc.addIceCandidate(candidate);

      } else {
        console.error('the message is invalid!', data)
      }
    }

    console.log("reveive client message", roomid,data);
  });

  socket.emit('join', roomid);
  return;
}

// 扑捉本地视频
function getMediaStream (stream) {

  localStream = stream;
  //2 ===============显示本地视频===============
  localVideo.srcObject = localStream;

  //这个函数的调用时机特别重要 一定要在getMediaStream之后再调用，否则会出现绑定失败的情况
  conn();
}

function handleError (err) {
  if (err) {
    console.error("getUserMedia  error:", err);
  }
}

// 第二步：采集本地视频
function start () {


  if (!navigator.mediaDevices ||
    !navigator.mediaDevices.getUserMedia) {
    console.log("getUserMedia is not supported!")
    return;
  } else {

    //1 ===============配置音视频参数===============
    var constraints = {
      video: true,
      audio: true
    }

    navigator.mediaDevices.getUserMedia(constraints)
      .then(getMediaStream)
      .catch(handleError)
  }
}

//关闭流通道
function closeLocalMedia () {
  if (localStream && localStream.getTracks()) {
    localStream.getTracks().forEach((track) => {
      track.stop();
    });
  }
  localStream = null;
}


function leave () {
  if (socket) {
    socket.emit('leave', roomid);
  }

  //释放资源
  closePeerConnection();
  closeLocalMedia();

  btnConn.disabled = false;
  btnLeave.disabled = true;
}

//创建本地流媒体链接
function createPeerConnection () {
  console.log('创建本地新的流媒体链接', pc);
  if (!pc) {
    pc = new RTCPeerConnection(pcConfig);
    console.log('==========', pc);
    pc.onicecandidate = (e) => {
      if (e.candidate) {
        sendMessage(roomid, {
          type: 'candidate',
          label: e.candidate.sdpMLineIndex,
          id: e.candidate.sdpMid,
          candidate: e.candidate.candidate
        });
      }
    }
    pc.ontrack = (e) => {
      console.log('123123123123', e);
      remoteVideo.srcObject = e.streams[0];
    }
  }
  if (pc === null || pc === undefined) {
    console.error('pc is null or undefined!');
    return;
  }

  if (localStream === null || localStream === undefined) {
    console.error('localStream is null or undefined!');
    return;
  }

  if (localStream) {
    console.log('开启新的通道,将数据推送过去',);
    localStream.getTracks().forEach((track) => {
      console.log('++++++++++', track);
      pc.addTrack(track, localStream);
    })
  }
}

//关闭本地媒体流链接
function closePeerConnection () {
  console.log('close RTCPeerConnection!');
  if (pc) {
    pc.close();
    pc = null;
  }
}

btnConn.onclick = connSignalServer;

btnLeave.onclick = leave;




